% 北太天元符号类
classdef MySym
    properties
        data % 数据, sympy 对象
    end
    
    methods
        % 构造函数
        function obj = MySym(var)
            % 导入 sympy 模块
            global already_init
            if isempty(already_init) || ~already_init
                py.importlib.import_module('sympy');
                already_init = true;
            end
            % 没有参数
            if nargin == 0
                obj.data = nan;
            else
                % 一个参数
                if isa(var, 'char') || isa(var, 'string')
                    obj.data = py.sympy.sympify(var);
                elseif isa(var, 'double') && isscalar(var)
                    var_str = num2str(var);
                    obj.data = py.sympy.sympify(var_str);
                end
            end
        end

        % [a,b,c,...] = to_sym(a,b,c,...) 可以把任意个变量转换为 MySym 类型
        function varargout = to_sym(varargin)
            varargout = cell(size(varargin));
            for i = 1:numel(varargin)
                if ~isa(varargin{i}, 'MySym')
                    varargout{i} = MySym(varargin{i});
                else
                    varargout{i} = varargin{i};
                end
            end
        end

        % 加法运算
        function result = plus(obj1, obj2)
            [obj1, obj2] = to_sym(obj1, obj2);
            % result.data = ['(' obj1.data, ') + (', obj2.data, ')'];
            % 在这里调用 python，实现符号表达式相加，然后返回一个

            % 这个函数用于通过SymPy实现两个符号表达式的加法
            result = MySym();
            result.data = obj1.data + obj2.data; % 执行加法并将结果转换回Matlab字符格式
        end
        
        % 减法运算
        function result = minus(obj1, obj2)
            [obj1, obj2] = to_sym(obj1, obj2);
            %result.data = ['(' obj1.data, ') - (', obj2.data, ')'];
           result = MySym();
            result.data = obj1.data-obj2.data;
        
        end
        
        % 乘法运算
        function result = times(obj1, obj2) % 算符 .*
            [obj1, obj2] = to_sym(obj1, obj2);
            %realPart = obj1.Real * obj2.Real - obj1.Imaginary * obj2.Imaginary;
            %imaginaryPart = obj1.Real * obj2.Imaginary + obj1.Imaginary * obj2.Real;
            %result = MyComplex(realPart, imaginaryPart);

            result = MySym();
            result.data = py.sympy.Mul(obj1.data, obj2.data);
        end
        
 % 除法运算
        function result = mrdivide(obj1, obj2) % 算符 .*
            [obj1, obj2] = to_sym(obj1, obj2);
            result = MySym();
            result.data = obj1.data/obj2.data;
        end




        function result = mtimes(obj1, obj2) % 算符 *
            result = times(obj1, obj2);
        end

        %除法运算
        function result = power(obj1, obj2) % .^ 算符
            [obj1, obj2] = to_sym(obj1, obj2);
            result = MySym();
            result.data = py.sympy.Pow(obj1.data, obj2.data);
        end

        function result = mpower(obj1, obj2) % ^ 算符
            result = power(obj1, obj2);
        end
        

     %微分运算
     function result = diff(obj1, obj2)
            [obj1, obj2] = to_sym(obj1, obj2);
            result = MySym();
            result.data = py.sympy.diff(obj1.data, obj2.data);
  
     end


 %积分运算
 function result = int(varargin)
        [varargin{:}] = to_sym(varargin{:});
        result = MySym();
        if nargin == 2
            expr = varargin{1};
            var = varargin{2};
            result.data = py.sympy.integrate(expr.data, var.data);
        elseif nargin == 4
             expr = varargin{1};
             var = varargin{2};
             a = varargin{3};
             b = varargin{4};
             abc = py.list();
             abc.append(var.data);
             abc.append(a.data);
             abc.append(b.data);
             abc = py.tuple(abc);
             result.data = py.sympy.integrate(expr.data, abc);
        % elseif 
        end
 end
 


  %求解运算
     function result = solve(obj1, obj2)
            [obj1, obj2] = to_sym(obj1, obj2);
            result = MySym();
            result.data = py.sympy.solve(obj1.data, obj2.data);
  
     end

     %简化表达式
     function result = simplify(obj1)
           % obj1= to_sym(obj1, obj2);
            result = MySym();
            result.data = py.sympy.simplify(obj1.data);
  
     end
        
        

        % 显示复数的字符串表示
        function display(obj)
            ret_str = char(py.str(obj.data));
            ret_str = strrep(ret_str, '**', '^');
            disp(ret_str);
        end
    end
end
